#include "particle.h"

#include <stdlib.h>
#include <SDL2/SDL_opengl.h>
#include <SDL2/SDL.h>

#include "dpi.h"

particle_system particle_init(int count, int depth) {
	particle_set *sets = malloc(sizeof(particle_set) * depth);
	for (size_t i = 0; i < depth; ++i) {
		sets[i].current_lifetime = 1.f;
		sets[i].particles = malloc(sizeof(particle) * count);
		sets[i].particle_count = count;
	}

	return (particle_system) { sets, depth, 0 };
}

static void random_vector(float magnitude, float *x, float *y) {
	float angle = (rand() / (float)RAND_MAX) * 6.28;
	*x = cos(angle) * magnitude;
	*y = sin(angle) * magnitude;
}

void particle_push(particle_system *system, curve_function cf, float t_start, float t_end) {
	//OutputDebugString("Pushing onto particle system...\n");
	particle_set *set = system->particle_sets + system->current_set;
	set->current_lifetime = 0.f;

	for (size_t i = 0; i < set->particle_count; ++i) {
		float t_0_1 = i / (set->particle_count - 1.f);
		float t = t_start + t_0_1 * (t_end - t_start);
		cf(t, &set->particles[i].x, &set->particles[i].y);

		random_vector(2, &set->particles[i].dx, &set->particles[i].dy);
		set->particles[i].radius = (rand() / (float)RAND_MAX) * 0.4f + 0.8f;
	}

	system->current_set = (system->current_set + 1) % system->set_count;
}

void particle_update(particle_system *system) {
	for (size_t i = 0; i < system->set_count; ++i) {
		particle_set *ps = system->particle_sets + i;
		ps->current_lifetime += 1 / 24.f;
		for (size_t j = 0; j < ps->particle_count; ++j) {
			particle *p = ps->particles + j;
			p->x += dpi_x(p->dx);
			p->y += dpi_y(p->dy);
		}
	}
}

void particle_destroy(particle_system *system) {
	for (size_t i = 0; i < system->set_count; ++i) {
		free(system->particle_sets[i].particles);
	}
	free(system->particle_sets);
}

void particle_render(particle_system *system, float r, float g, float b, float alpha_multiplier) {
	//OutputDebugString("Rendering particles...\n");
	//char help[128];
	//SDL_snprintf(help, 128, "250: %f %f\n", system->particle_sets[0].particles[250].x, system->particle_sets[0].particles[250].y);
	//OutputDebugString(help);
	
	for (size_t i = 0; i < system->set_count; ++i) {
		particle_set *ps = system->particle_sets + i;
		float alpha = 1.f - ps->current_lifetime;
		alpha *= alpha_multiplier;
		float radius = dpi_x(1.2f - 0.6f * ps->current_lifetime);
		float rn = (1 - r) * ps->current_lifetime + r;
		float bn = (1 - b) * ps->current_lifetime + b;
		float gn = (1 - g) * ps->current_lifetime + g;

		glColor4f(rn, gn, bn, alpha);

		for (size_t j = 0; j < ps->particle_count; ++j) {
			particle *p = ps->particles + j;
			float r = p->radius * radius;
			
			/*glBegin(GL_TRIANGLE_FAN);
			glVertex2f(p->x, p->y);
			for (size_t step = 0; step <= 8; ++step) {
				glVertex2f(p->x + cos(step * 6.28 / 8) * radius, p->y + sin(step * 6.28 / 8) * radius);
			}
			glEnd();*/
			glBegin(GL_QUADS);
			glVertex2f(p->x - r, p->y);
			glVertex2f(p->x, p->y + r);
			glVertex2f(p->x + r, p->y);
			glVertex2f(p->x, p->y - r);
			glEnd();
		}
	}
}